package com.ruoyi.web.controller.dingtalk;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.github.stuxuhai.jpinyin.PinyinFormat;
import com.github.stuxuhai.jpinyin.PinyinHelper;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.dingtalk.config.AppConfig;
import com.ruoyi.dingtalk.domain.DepartmentDTO;
import com.ruoyi.dingtalk.domain.ServiceResult;
import com.ruoyi.dingtalk.domain.UserDTO;
import com.ruoyi.dingtalk.domain.UserInfoDTO;
import com.ruoyi.dingtalk.service.DingtalkTokenService;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
import com.taobao.api.ApiException;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.*;

import static com.ruoyi.dingtalk.config.UrlConstant.*;


/**
 * 微应用QuickStart示例，访问联系人API
 *
 * @author openapi@dingtalk
 * @date 2020/2/4
 */
@RestController
@RequestMapping("/dingtalk")
/** @CrossOrigin("*") // NOTE：此处仅为本地调试使用，为避免安全风险，生产环境请勿设置CORS为 '*' */
public class ContactController {
    private static final Logger log = LoggerFactory.getLogger(ContactController.class);

    private DingtalkTokenService dingtalkTokenService;
    private AppConfig appConfig;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private ISysPostService postService;

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    public ContactController(DingtalkTokenService dingtalkTokenService, AppConfig appConfig) {
        this.dingtalkTokenService = dingtalkTokenService;
        this.appConfig = appConfig;
    }

    /**
     * 根据钉钉详细信息创建用户到本地系统中
     * @param map
     * @return
     */
    @PreAuthorize("@ss.hasPermi('system:user:add')")
    @PostMapping("/createDingtalkToUsers")
    public AjaxResult createDingtalkToUsers(@RequestBody Map<String,Object> map){
        /** 根据USERID查询出钉钉信息 */
        System.out.println(map);
        /** 查询有没有该用户 */
        SysUser user = userService.selectUserByUserName((String) map.get("userid"));
        if (user == null) {
            /** 创建用户 */
            OapiV2UserGetResponse.UserGetResponse userGetResponse = userListByUserid((String) map.get("userid"));
            user=conversionClass(userGetResponse);
            userService.insertUser(user);
            return AjaxResult.success("新增完成");
        } else {
            return AjaxResult.error("新增用户失败，登录账号已存在");
        }

    }

    /**
     * map转换成sysUser类
     * @param userGetResponse
     * @return
     */
    public SysUser conversionClass(OapiV2UserGetResponse.UserGetResponse userGetResponse) {
        SysUser user=new SysUser();
        user.setPassword(SecurityUtils.encryptPassword("123456"));
        user.setAvatar(userGetResponse.getAvatar());
        user.setEmail(userGetResponse.getEmail());
        user.setNickName(userGetResponse.getName());
        user.setPhonenumber(userGetResponse.getMobile());
        user.setSex("2");
        user.setDelFlag("0");
		// user.setLoginType("dingtalk");
		user.setIdentityType("dingtalk");
        user.setUserName(userGetResponse.getUserid());
        List<SysRole> listRole = new ArrayList<>();
        /** 默认角色 */
        SysRole sysRole=new SysRole();
        sysRole.setIsDefault("Y");
        List<SysRole> sysRoles = roleService.selectRoleList(sysRole);
        listRole.addAll(sysRoles);
        user.setRoles(listRole);
        Long[] longs=new Long[sysRoles.size()];
        for (int i = 0; i < sysRoles.size();i++) {
            longs[i] = sysRoles.get(i).getRoleId();
        }
        user.setRoleIds(longs);
        /** 状态 */
        user.setStatus("0");
        user.setCreateBy(SecurityUtils.getUsername());
        user.setRemark("由钉钉接口加入用户");
        /** 新增职位 */
        user.setPostIds(getPostByPostName(userGetResponse.getTitle()));
        /** 新增部门 */
        user.setDeptId(getDeptByUserid(userGetResponse.getUserid()));
        user.setSalt("anan");
        return user;
    }

    /**
     * 查询是否已经有该部门，如果有，则返回该部门ID，如果没有则逐个新增部门并返回
     * @param userId
     * @return
     */
    public Long getDeptByUserid(String userId) {
        String accessToken=getDingtalkToken();
        DingTalkClient client = new DefaultDingTalkClient(URL_DEPARTMENT_LISTPARENTBYUSER);
        OapiV2DepartmentListparentbyuserRequest req = new OapiV2DepartmentListparentbyuserRequest();
        req.setUserid(userId);
        OapiV2DepartmentListparentbyuserResponse rsp = null;
        try {
            rsp = client.execute(req, accessToken);
        } catch (ApiException e) {
            e.printStackTrace();
        }
        List<Long> parentDeptIdList = rsp.getResult().getParentList().get(0).getParentDeptIdList();
        SysDept dept=null;
        for (int i = parentDeptIdList.size()-1; i >= 0 ; i--) {
            if (parentDeptIdList.get(i) != 1L) {
                dept = deptService.selectDeptByDdId(parentDeptIdList.get(i));
                if (dept == null) {
                    dept = new SysDept();
                    OapiV2DepartmentGetResponse.DeptGetResponse deptGetResponse = getDepartmentByDeptId(parentDeptIdList.get(i));
                    dept.setDeptName(deptGetResponse.getName());
                    dept.setLeader("安安");
                    dept.setPhone("15888888888");
                    dept.setEmail("anan@gmq.com");
                    dept.setCreateBy(SecurityUtils.getUsername());
                    dept.setParentId(deptGetResponse.getParentId() == 1L ? 100L :
                                    deptService.selectDeptByDdId(deptGetResponse.getParentId()).getDeptId());
                    dept.setDdDeptId(deptGetResponse.getDeptId());
                    deptService.insertDept(dept);
                }
            }
        }
        return dept.getDeptId();
    }

    /**
     *
     */
    public OapiV2DepartmentGetResponse.DeptGetResponse getDepartmentByDeptId(Long deptId){
        String accessToken=getDingtalkToken();
        DingTalkClient client = new DefaultDingTalkClient(URL_DEPARTMENT_GET);
        OapiV2DepartmentGetRequest req = new OapiV2DepartmentGetRequest();
        req.setDeptId(deptId);
        OapiV2DepartmentGetResponse rsp = null;
        try {
            rsp = client.execute(req, accessToken);
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return rsp.getResult();
    }

    /**
     * 返回职位ID
     * 先进行查询是否已经有该职位，如果有，则返回该职位，如果没有则新增职位，再返回ID
     * @param title
     * @return
     */
    public Long[] getPostByPostName(String title) {
        SysPost post=new SysPost();
        post.setPostName(title);
        List<SysPost> sysPosts = postService.selectPostList(post);
        Long[] postids = new Long[1];
        if (sysPosts.size() > 0) {
            postids[0] = sysPosts.get(0).getPostId();
        } else {
            post = new SysPost();try {
                post.setPostCode(PinyinHelper.convertToPinyinString(title, "", PinyinFormat.WITHOUT_TONE));
            } catch (Exception e) {
                e.printStackTrace();
            }
            post.setPostName(title);
            post.setPostSort("1000");
            post.setStatus("0");
            post.setCreateBy(SecurityUtils.getUsername());
            postService.insertPost(post);
            postids[0] = post.getPostId();
        }
        return postids;
    }

    /**
     * 获取部门列表 V2
     * @param id
     * @return
     */
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @GetMapping("/department/list")
    public ServiceResult<List<DepartmentDTO>> listDepartment2(@RequestParam(value = "id", required = false, defaultValue = "1") String id) {
        String accessToken=getDingtalkToken();
        DingTalkClient client = new DefaultDingTalkClient(URL_DEPARTMENT_LIST);
        OapiDepartmentListRequest req = new OapiDepartmentListRequest();
        req.setId(id);
        req.setHttpMethod("GET");
        OapiDepartmentListResponse rsp;
        try {
            rsp = client.execute(req, accessToken);
        } catch (ApiException e) {
            log.error("Failed to {}", URL_DEPARTMENT_LIST, e);
            return ServiceResult.failure(e.getErrCode(), "Failed to listDepartment: " + e.getErrMsg());
        }
        if (!rsp.isSuccess()) {
            return ServiceResult.failure(rsp.getErrorCode(), rsp.getErrmsg());
        }
        if (CollectionUtils.isNotEmpty(rsp.getDepartment())) {
            List<DepartmentDTO> results = new ArrayList<>(rsp.getDepartment().size());
            for (OapiDepartmentListResponse.Department department : rsp.getDepartment()) {
                DepartmentDTO departmentDTO = new DepartmentDTO();
                departmentDTO.setId(department.getId());
                departmentDTO.setName(department.getName());
                departmentDTO.setCreateDeptGroup(department.getCreateDeptGroup());
                departmentDTO.setAutoAddUser(department.getAutoAddUser());
                departmentDTO.setParentid(department.getParentid());
                results.add(departmentDTO);
            }
            return ServiceResult.success(results);
        }
        return ServiceResult.success(Collections.emptyList());
    }

    /**
     * 获取部门信息 V2
     * @param id
     * @param offset
     * @param size
     * @param order
     * @return
     */
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @GetMapping("/user/simplelist")
    public ServiceResult<List<UserDTO>> listDepartmentUsers(
            @RequestParam("department_id") Long id,
            @RequestParam(name = "offset", required = false, defaultValue = "0") Long offset,
            @RequestParam(name = "size", required = false, defaultValue = "50") Long size,
            @RequestParam(name = "order", required = false, defaultValue = "entry_desc") String order
    ) {
        String accessToken=getDingtalkToken();
        DingTalkClient client = new DefaultDingTalkClient(URL_DEPARTMENT_LIST);
        OapiV2UserListRequest req = new OapiV2UserListRequest();
        req.setDeptId(Long.valueOf(id));
        req.setCursor(offset);
        req.setSize(size);
        req.setOrderField(order);
        req.setHttpMethod("GET");
        OapiV2UserListResponse rsp;
        try {
            rsp = client.execute(req, accessToken);
        } catch (ApiException e) {
            log.error("Failed to {}", URL_DEPARTMENT_LIST, e);
            return ServiceResult.failure(e.getErrCode(), "Failed to listDepartment: " + e.getErrMsg());
        }
        if (!rsp.isSuccess()) {
            return ServiceResult.failure(rsp.getErrorCode(), rsp.getErrmsg());
        }
        if (CollectionUtils.isNotEmpty(rsp.getResult().getList())) {
            List<UserDTO> results = new ArrayList<>(rsp.getResult().getList().size());
            for (OapiV2UserListResponse.ListUserResponse userlist: rsp.getResult().getList()) {
                UserDTO user = new UserDTO();
                user.setUserid(userlist.getUserid());
                user.setName(userlist.getName());
                results.add(user);
            }
            return ServiceResult.success(results);
        }
        return ServiceResult.success(Collections.emptyList());
    }

    /**
     * 根据部门ID获取用户信息
     * @param id
     * @param offset
     * @param size
     * @param order
     * @return
     */
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @GetMapping("/user/listbypage")
    public ServiceResult<List<UserInfoDTO>> listbypage(
            @RequestParam("department_id") Long id,
            @RequestParam(name = "offset", required = false, defaultValue = "0") Long offset,
            @RequestParam(name = "size", required = false, defaultValue = "50") Long size,
            @RequestParam(name = "order", required = false, defaultValue = "entry_desc") String order
    ) {
        String accessToken=getDingtalkToken();
        DingTalkClient client = new DefaultDingTalkClient(URL_USER_LIST);
        OapiV2UserListRequest req = new OapiV2UserListRequest();
        req.setDeptId(id);
        req.setCursor(offset);
        req.setSize(size);
        req.setOrderField(order);
        req.setHttpMethod("GET");
        OapiV2UserListResponse rsp;
        try {
            rsp = client.execute(req, accessToken);
        } catch (ApiException e) {
            log.error("Failed to {}", URL_USER_LIST, e);
            return ServiceResult.failure(e.getErrCode(), "Failed to listDepartment: " + e.getErrMsg());
        }
        if (!rsp.isSuccess()) {
            return ServiceResult.failure(rsp.getErrorCode(), rsp.getErrmsg());
        }
        if (CollectionUtils.isNotEmpty(rsp.getResult().getList())) {
            List<UserInfoDTO> results = new ArrayList<>(rsp.getResult().getList().size());
            List<OapiV2UserListResponse.ListUserResponse> userlists = rsp.getResult().getList();
            for (int i =0 ; i<userlists.size();i++){
                UserInfoDTO userInfoDTO= Convert.convert(UserInfoDTO.class,userlists.get(i));
                results.add(userInfoDTO);
            }
            return ServiceResult.success(results);
        }
        return ServiceResult.success(Collections.emptyList());
    }

    /**
     * 获取部门及下级部门全部用户信息
     * @param id
     * @param offset
     * @param size
     * @param order
     * @return
     */
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @GetMapping("/user/listbypageAndChildren")
    public ServiceResult<Set<UserInfoDTO>> listbypageAndChildren(
            @RequestParam(name = "deptId", required = false, defaultValue = "1") String id,
            @RequestParam(name = "offset", required = false, defaultValue = "0") Long offset,
            @RequestParam(name = "size", required = false, defaultValue = "50") Long size,
            @RequestParam(name = "order", required = false, defaultValue = "entry_desc") String order
    ) {
        String[] idArr = Convert.toStrArray(id);
        List<UserInfoDTO> result = new ArrayList<>();
        for (String str:idArr) {
            ServiceResult<List<UserInfoDTO>> listbypage = listbypage(Long.valueOf(str), offset, size, order);
            if (listbypage.isSuccess() && listbypage.getResult().size()>0) {
                result.addAll(listbypage.getResult());
            }
        }
        // 利用SET特性，去掉重复对象
        Set<UserInfoDTO> resultSet = new HashSet<UserInfoDTO>(result);
        System.out.println(result);
        return ServiceResult.success(resultSet);
    }


    /**
     * 根据userid获取用户详情
     * @param userid
     * @return
     */
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @GetMapping("/user/deptListByUserId")
    public ServiceResult<List<UserInfoDTO>> deptListByUserId(@RequestParam(name="userid",required = false,defaultValue = "") String userid){
        String accessToken=getDingtalkToken();
        List<UserInfoDTO> result = new ArrayList<>();
        if (!userid.isEmpty()){
            DingTalkClient client = new DefaultDingTalkClient(TOPAPI_USER_GET);
            OapiV2UserGetRequest req = new OapiV2UserGetRequest();
            req.setUserid(userid);
            req.setLanguage("zh_CN");
            OapiV2UserGetResponse rsp = null;
            try {
                rsp = client.execute(req, accessToken);
                if (rsp.isSuccess()){
                    JSONObject userlists = JSON.parseObject(rsp.getBody()).getJSONObject("result");
                    userlists.put("jobnumber", userlists.getString("job_number"));
                    UserInfoDTO userInfoDTO= Convert.convert(UserInfoDTO.class,userlists);
                    result.add(userInfoDTO);
                }
            } catch (ApiException e) {
                e.printStackTrace();
            }
            System.out.println(rsp.getBody());
        }
        return ServiceResult.success(result);
    }

    /**
     * 根据userid获取用户详情
     * @param userid
     * @return
     */
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @GetMapping("/user/userListByUserid")
    public OapiV2UserGetResponse.UserGetResponse userListByUserid(@RequestParam(name="userid",required = false,defaultValue = "") String userid){
        String accessToken=getDingtalkToken();
        List<UserInfoDTO> result = new ArrayList<>();
        if (!userid.isEmpty()){
            DingTalkClient client = new DefaultDingTalkClient(TOPAPI_USER_GET);
            OapiV2UserGetRequest req = new OapiV2UserGetRequest();
            req.setUserid(userid);
            req.setLanguage("zh_CN");
            OapiV2UserGetResponse rsp = null;
            try {
                rsp = client.execute(req, accessToken);
                if (rsp.isSuccess()){
                    return rsp.getResult();
                }
            } catch (ApiException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 根据手机号获取用户详细信息
     * @param mobile
     * @return
     */
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @GetMapping("/user/deptListByMobile")
    public ServiceResult<List<UserInfoDTO>> deptListByMobile(@RequestParam(name="mobile",defaultValue = "") String mobile){
        String accessToken=getDingtalkToken();
        List<UserInfoDTO> result = new ArrayList<>();
        if (!mobile.isEmpty()){
            DingTalkClient client = new DefaultDingTalkClient(TOPAPI_USER_MOBILE);
            OapiV2UserGetbymobileRequest req=new OapiV2UserGetbymobileRequest();
            req.setMobile(mobile);
            OapiV2UserGetbymobileResponse rsp=null;
            try {
                rsp = client.execute(req, accessToken);
                if (rsp.isSuccess()){
                    JSONObject userlists = JSON.parseObject(rsp.getBody()).getJSONObject("result");
                    return deptListByUserId(userlists.getString("userid"));
                }
            } catch (ApiException e) {
                e.printStackTrace();
            }
        }
        return ServiceResult.success(result);

    }

    /**
     * 获取token
     * @return
     */
    public String getDingtalkToken(){
        ServiceResult<String> accessTokenSr = dingtalkTokenService.getAccessToken();
        if (accessTokenSr.isSuccess()) {
            return accessTokenSr.getResult();
        }
        return "";
    }

}
